import type {JsonResult, LoginData, LoginSuccessData} from "@/http/index.tsx";
import LogFactory from "@/log/LogFactory.tsx";

const log = LogFactory.getLogger("RequestHandler")
const BASE_URL = import.meta.env.VITE_REQUEST_BASE_URL;

const getHeaders = () => {
    return {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
        'Authorization': 'Bearer ' + localStorage.getItem('user.login.token')
    };
}

/**
 * GET 请求获取服务器资源
 * @param url 请求地址
 */
export const get = async function <T>(url: string): Promise<JsonResult<T>> {
    return await fetch(BASE_URL + url, {method: 'GET', headers: getHeaders()})
        .then(handlerResponse)
        .catch(handlerError) as Promise<JsonResult<T>>
}
/**
 * POST 请求, 添加新的资源
 * @param url 请求地址
 * @param data 请求携带的数据
 */
export const post = async function <T>(url: string, data: object): Promise<JsonResult<T>> {
    return await fetch(BASE_URL + url, {method: 'POST', headers: getHeaders(), body: JSON.stringify(data)})
        .then(handlerResponse)
        .catch(handlerError) as Promise<JsonResult<T>>
}
/**
 * PUT 请求, 更新服务资源,对资源全量更新
 * @param url 请求地址
 * @param data 请求携带的数据
 */
export const put = async function <T>(url: string, data: object): Promise<JsonResult<T>> {
    return await fetch(BASE_URL + url, {method: 'PUT', headers: getHeaders(), body: JSON.stringify(data)})
        .then(handlerResponse)
        .catch(handlerError) as Promise<JsonResult<T>>
}
/**
 * PATCH 请求, 更新服务资源,对资源进行部分更新
 * @param url 请求地址
 * @param data 请求携带的数据
 */
export const patch = async function <T>(url: string, data: object): Promise<JsonResult<T>> {
    return await fetch(BASE_URL + url, {method: 'PATCH', headers: getHeaders(), body: JSON.stringify(data)})
        .then(handlerResponse)
        .catch(handlerError) as Promise<JsonResult<T>>
}
/**
 * DELETE 请求, 删除服务器资源
 * @param url 请求地址
 * @param data 请求携带的数据
 */
export const del = async function <T>(url: string, data?: object): Promise<JsonResult<T>> {
    return await fetch(BASE_URL + url, {method: 'DELETE', headers: getHeaders(), body: JSON.stringify(data)})
        .then(handlerResponse)
        .catch(handlerError) as Promise<JsonResult<T>>
}

export const login = async function (data: LoginData): Promise<JsonResult<LoginSuccessData>> {
    return await fetch(BASE_URL + "/login", {
        method: "POST",
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
        },
        body: `username=${data.username}&password=${data.password}`
    }).then(handlerResponse)
        .catch((err: unknown) => {
            log.error("用户登录失败", data, err)
        }) as Promise<JsonResult<LoginSuccessData>>
}


const handlerResponse = (response: Response) => {

    if (!response.ok) {
        log.warn("当前请求失败: 响应状态码", response.status)
        throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
}

const handlerError = (error: unknown) => {
    log.error("error", error);
}